﻿using System;
using System.Linq;
using Windows.ApplicationModel;
using Windows.Security.Credentials;
using Windows.Security.Cryptography;
using Windows.System.Profile;

namespace com.IronOne.BoardPACWinAppUtil.Security
{
    public class DeviceService
    {
        /// <summary>
        ///     Get the ASHWID and returns it
        ///     If not found Generates an ASHWID and returns it
        ///     Refer Package.appxmanifest's packaging section for possible values
        /// </summary>
        public static string GetAppSpecificHardwareId()
        {
            var vault = new PasswordVault();
            var resourceName = Package.Current.DisplayName; // Value: BoardPAC
            var deviceName = Package.Current.Id.Name; // Value: com.IronOne.IronOne.BoardPACWinAppDEV
            var deviceId = "";
            PasswordCredential credential;

            //Here if resource not found an exception is thrown by .net
            //instead of returning null.
            try
            {
                credential = vault.FindAllByResource(resourceName).FirstOrDefault();
            }
            catch (Exception)
            {
                credential = null;
            }

            if (credential != null) //Device id exist so return it
            {
                // Retrieves the actual userName and password.
                deviceId = vault.Retrieve(resourceName, deviceName).Password;
            }

            if (credential == null) //App's first time, so create a device id and save it
            {
                deviceId =
                    CryptographicBuffer.EncodeToBase64String(HardwareIdentification.GetPackageSpecificToken(null).Id);
                deviceId = new Random().Next(100000, 9999999) + deviceId;

                //NOTE: '+' Doesn't support on the backend web
                deviceId = deviceId.Replace("+", "_");
                credential = new PasswordCredential(resourceName, deviceName, deviceId);
                vault.Add(credential); // Permanently stores credential in the password vault.
                return deviceId;
            }

            return deviceId;
        }

        public static bool RemoveAppSpecificHardwareId()
        {
            try
            {
                var vault = new PasswordVault();
                var resourceName = Package.Current.DisplayName; // Value: BoardPAC
                //var deviceName = Package.Current.Id.Name; // Value: com.IronOne.IronOne.BoardPACWinAppDEV
                PasswordCredential credential;

                //Here if resource not found an exception is thrown by .net
                //instead of returning null.
                try
                {
                    credential = vault.FindAllByResource(resourceName).FirstOrDefault();
                }
                catch (Exception)
                {
                    credential = null;
                }

                if (credential != null) //Device id exist so remove it
                    vault.Remove(credential);

                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>
        ///     Get the windows app version
        ///     Returns string version as "3.20.20"
        /// </summary>
        public static string GetAppVersion()
        {
            var ver = Package.Current.Id.Version;
            return ver.Major + "." + ver.Minor + "." + ver.Build;
        }
    }
}